﻿using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
using System.IO;
using System.Threading;
using Commons;

namespace Web
{
    public class Global : System.Web.HttpApplication
    {
        public DaemonThreads _Daemon
        {
            get
            {
                if (Application["_WebBoss_Daemon"] == null)
                    Application["_WebBoss_Daemon"] = new DaemonThreads();
                return Application["_WebBoss_Daemon"] as DaemonThreads;
            }
        }

        protected void Application_Start(object sender, EventArgs e)
        {
            _Daemon.Start();
            SaveLog.WriteFormatLog("WebBoss Application Start");
        }

        protected void Application_End(object sender, EventArgs e)
        {
            _Daemon.Abort();
            SaveLog.WriteFormatLog("WebBoss Application End");
        }

        protected void Application_Error(object sender, EventArgs e)
        {
            //测试站点为了能看到错误提示注释掉了，正式站点必须打开注释

            bool IsRecord = false;
            if (System.Configuration.ConfigurationManager.AppSettings["RecordErrorStackTrace"] != null)
                IsRecord = System.Configuration.ConfigurationManager.AppSettings["RecordErrorStackTrace"].ToUpper() == "TRUE";
            try
            {
                string UserId = Session["UserId"] == null ? "" : Session["UserId"].ToString();
                SaveLog.WriteFormatLog("用户信息:{0} 服务器IP:{1} 客户IP:{2}", UserId, Request.ServerVariables["LOCAL_ADDR"], Commons.NetSocket.getAllIp());
                if (Server.GetLastError().InnerException == null)
                {
                    SaveLog.WriteFormatLog("错误消息:{0} 地址：{1}", Server.GetLastError().Message, Request.Url.AbsolutePath);
                    if (IsRecord)
                        SaveLog.WriteFormatLog("错误堆栈:{0}", Server.GetLastError().StackTrace);
                }
                else
                {
                    SaveLog.WriteFormatLog("错误消息:{0} 地址：{1}", Server.GetLastError().InnerException.Message, Request.Url.AbsolutePath);
                    if (IsRecord)
                        SaveLog.WriteFormatLog("错误堆栈:{0}", Server.GetLastError().InnerException.StackTrace);

                    #region 处理自定义异常
                    if (Server.GetLastError().InnerException is Base.CustomException)
                    {
                        Base.CustomException ce = Server.GetLastError().InnerException as Base.CustomException;
                        if (ce != null)
                        {
                            ce.CustomHandle();
                            return;
                        }
                    }
                    #endregion
                }
            }
            catch
            {
                //throw new Exception("应用程序错误");
            }

            #region 是否清除错误
            bool IsRecordToFile = false;
            if (System.Configuration.ConfigurationManager.AppSettings["IsClearError"] != null)
                IsRecordToFile = System.Configuration.ConfigurationManager.AppSettings["IsClearError"].ToUpper() == "TRUE";
            if (IsRecordToFile)
            {
                Server.ClearError();
                HttpContext.Current.Response.Redirect("~/NoPower.aspx?ErrorCode=0");
            }
            #endregion
        }

        protected void Session_Start(object sender, EventArgs e)
        {
            int timeout = 20;
            if (System.Configuration.ConfigurationManager.AppSettings["ActiveTimeout"] != null)
            {
                try
                {
                    timeout = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["ActiveTimeout"]);
                }
                catch { }
            }
            Session.Timeout = timeout;
            if (!_Daemon.IsAlive)
                _Daemon.Start();
            //SaveLog.WriteFormatLog("SessionID:{0} Start;TimeOut:{1}", Session.SessionID, timeout);
        }

        protected void Session_End(object sender, EventArgs e)
        {
            Session.Clear();
            Session.Abandon();
            //SaveLog.WriteFormatLog("SessionID:{0} End;", Session.SessionID);
        }
    }

    public class DaemonThreads
    {
        private bool _IsAbort;

        public bool IsAlive
        {
            get { return _t.IsAlive; }
        }
        private Thread _t;
        private string _DaemonPath;

        public DaemonThreads()
        {
            _IsAbort = false;
            _DaemonPath = HttpContext.Current.Server.MapPath("~/App_Data/ViewState/");
        }

        public DaemonThreads(string Path)
        {
            _IsAbort = false;
            _DaemonPath = Path;
        }

        public void MonitorViewState()
        {
            while (true)
            {
                if (_IsAbort) Thread.CurrentThread.Abort();

                try
                {
                    DirectoryInfo dir = new DirectoryInfo(_DaemonPath);
                    if (!dir.Exists)
                        dir.Create();
                    else
                    {
                        int timeout = 20;
                        if (System.Configuration.ConfigurationManager.AppSettings["ActiveTimeout"] != null)
                        {
                            try
                            {
                                timeout = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["ActiveTimeout"]);
                            }
                            catch { }
                        }

                        DateTime nt = DateTime.Now.AddMinutes(-1 * timeout - 1);
                        foreach (FileInfo f in dir.GetFiles())
                            if (f.CreationTime < nt)
                                try { f.Delete(); }
                                catch (Exception exp1)
                                {
                                    SaveLog.WriteFormatLog("WebBoss MonitorViewState Thread 删除过期文件失败 异常:" + exp1.Message);
                                }
                    }
                }
                catch (Exception exp2)
                {
                    SaveLog.WriteFormatLog("WebBoss MonitorViewState Thread 异常:" + exp2.Message);
                }
                SaveLog.WriteFormatLog("WebBoss MonitorViewState Thread Running");
                Thread.Sleep(60000);//1800000 30分钟
            }
        }

        public void Start()
        {
            _t = new Thread(new ThreadStart(MonitorViewState));
            _t.Start();
            SaveLog.WriteFormatLog("WebBoss MonitorViewState Thread Start");
        }

        public void Abort()
        {
            _t.Abort();
            _IsAbort = true;
            SaveLog.WriteFormatLog("WebBoss MonitorViewState Thread Abort");
        }
    }
}